package com.logic.modular.game.alliance.service;

import com.comment.exception.ServiceException;
import com.logic.modular.game.battle.info.base.PvpPlayerInfoServiceImpl;
import com.logic.modular.game.alliance.domain.AlliancePanel;
import com.logic.modular.game.alliance.domain.AllianceStatus;
import com.logic.modular.game.player.info.service.PlayerStatusServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 结盟服务
 */
@Slf4j
@Service
public class AllianceServiceImpl {
    @Resource
    private PlayerStatusServiceImpl playerStatusService;
    @Resource
    private PvpPlayerInfoServiceImpl pvpPlayerInfoServiceImpl;

    public AlliancePanel alliancePanel(Long playerId) {
        Long ownerMatchId = playerStatusService.currentMatchId(playerId);
        if (ownerMatchId == null || ownerMatchId == 0 || ownerMatchId == -1) {
            throw new ServiceException("当前没有对局");
        }
        return AlliancePanel.tryInit(ownerMatchId);
    }

    public void leaveTheAlliance(Long playerId) {
        Long ownerMatchId = playerStatusService.currentMatchId(playerId);
        if (ownerMatchId == null) {
            throw new ServiceException("当前没有对局");
        }
        AlliancePanel alliancePanel = AlliancePanel.tryInit(ownerMatchId);
        boolean b = alliancePanel.leaveTheAlliance(playerId);
        if (!b) {
            throw new ServiceException("离开联盟失败");
        } else {
            updatePvpPlayerAlliance(playerId, alliancePanel, ownerMatchId);
        }
    }

    private void updatePvpPlayerAlliance(Long playerId, AlliancePanel alliancePanel, Long ownerMatchId) {
        Map<String, String> playerIds = alliancePanel.getPlayerIds();
        pvpPlayerInfoServiceImpl.mapCache(ownerMatchId).forEach((k, pvpPlayerInfo) -> {
            Set<Long> alliesUidList = pvpPlayerInfo.getAlliesUidList();

            String playerIdString = playerId.toString();
            boolean b1 = playerIds.containsKey(playerIdString);
            if (b1) {
                String alliancePanelNo = playerIds.get(playerIdString);
                AllianceStatus allianceStatus = alliancePanel.getInfo().get(alliancePanelNo);
                if (allianceStatus.getStatus() == 1) {
                    Set<Long> collect = allianceStatus.getInfo().keySet().stream().mapToLong(Long::parseLong).boxed().collect(Collectors.toSet());
                    if (!alliesUidList.equals(collect)) {
                        pvpPlayerInfo.setAlliesUidList(collect);
                        pvpPlayerInfoServiceImpl.update(pvpPlayerInfo);
                    }
                }
            } else {
                Set<Long> singleton = Collections.singleton(playerId);
                if (!alliesUidList.equals(singleton)) {
                    pvpPlayerInfo.setAlliesUidList(singleton);
                    pvpPlayerInfoServiceImpl.update(pvpPlayerInfo);
                }
            }
        });
    }

    public void refuse(Long playerId, String no) {
        Long ownerMatchId = playerStatusService.currentMatchId(playerId);
        if (ownerMatchId == null) {
            throw new ServiceException("当前没有对局");
        }
        AlliancePanel alliancePanel = AlliancePanel.tryInit(ownerMatchId);
        boolean b = alliancePanel.refuse(playerId, no);
        if (!b) {
            throw new ServiceException("拒绝联盟失败");
        }else {
            updatePvpPlayerAlliance(playerId, alliancePanel, ownerMatchId);
        }
    }

    public void tryAlliance(Long playerId, Long targetPlayerId) {
        Long targetMatchId = playerStatusService.currentMatchId(targetPlayerId);
        Long ownerMatchId = playerStatusService.currentMatchId(playerId);
        if (targetMatchId == null || ownerMatchId == null) {
            throw new ServiceException("当前没有对局");
        }
        if (!targetMatchId.equals(ownerMatchId)) {
            throw new ServiceException("非同比赛无法组队");
        }
        AlliancePanel alliancePanel = AlliancePanel.tryInit(ownerMatchId);
        boolean b = alliancePanel.tryAlliance(playerId, targetPlayerId);
        if (b) {
            updatePvpPlayerAlliance(playerId, alliancePanel, ownerMatchId);
        }
    }
}
